%%% Copyright 2010 Google Inc.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
%%%
%%%     http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing, software
%%% distributed under the License is distributed on an "AS IS" BASIS,
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.

%%% @copyright 2010 Google Inc.
%%% @author <jacoby@google.com> Jacoby Thwaites [http://sites/madcloud]
%%% @version {@version}
%%% @doc
%%% Functions to backup and restore the tables maintained by prog module.
%%%
%%% These functions can be used from the shell while the txm system is
%%% running. Beware that the restore/1 function entirely overwrites the
%%% current database.
%%%
%%% @headerfile "../include/txm.hrl"

-module(backup).

-include("txm.hrl").

-export([backup/1, restore/1]).
-export([change_node_name/4]).

%% @doc Creates a checkpoint and backs up the mnesia tables on the node
%% to `Filename'.
backup(Filename) ->
  mnesia:backup(Filename).

%% @doc Restores the field, folder and op tables from the specified backup,
%% assuming the nodename is correct in the backup file. Existing tables are
%% cleared of entries first.
restore(Filename) ->
  mnesia:restore(Filename, [{clear_tables, ?TABLES},
                            {skip_tables, [activation]}]).

%% @doc Changes the `From' erlang node name in the 'Source' backup, writing
%% a new `Target' backup file with the `To' nodename.
change_node_name(From, To, Source, Target) ->
  Switch =
    fun(Node) when Node == From -> To;
      (Node) when Node == To -> throw({error, already_exists});
      (Node) -> Node
    end,
  Convert =
    fun({schema, db_nodes, Nodes}, Acc) ->
         {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
      ({schema, version, Version}, Acc) ->
        {[{schema, version, Version}], Acc};
      ({schema, cookie, Cookie}, Acc) ->
        {[{schema, cookie, Cookie}], Acc};
      ({schema, Tab, CreateList}, Acc) ->
        Keys = [ram_copies, disc_copies, disc_only_copies],
        OptSwitch =
          fun({Key, Val}) ->
               case lists:member(Key, Keys) of
                 true -> {Key, lists:map(Switch, Val)};
                 false-> {Key, Val}
                 end
          end,
        {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc};
      (Other, Acc) ->
        {[Other], Acc}
    end,
  mnesia:traverse_backup(Source, Target, Convert, switched).
